/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * LincolnLogLite.java
 *
 * Created on Dec 9, 2010, 9:46:38 PM
 */
package org.schwiet.LincolnLog.ui;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.ScrollPaneConstants;
import org.apache.log4j.Logger;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.transitions.ScreenTransition;
import org.jdesktop.animation.transitions.TransitionTarget;
import org.schwiet.LincolnLog.divvy.Divvy;
import org.schwiet.LincolnLog.divvy.DivvyForm;
import org.schwiet.LincolnLog.divvy.DivvyManager;
import org.schwiet.LincolnLog.divvy.DivvySummary;
import org.schwiet.LincolnLog.divvy.DivvyUtility;
import org.schwiet.LincolnLog.divvy.commands.DeleteDivviesCommand;
import org.schwiet.LincolnLog.divvy.commands.ResetDivviesCommand;
import org.schwiet.LincolnLog.transaction.ui.NewTransactionForm;
import org.schwiet.LincolnLog.ui.command.CommandDispatch;
import org.schwiet.LincolnLog.ui.components.BottomBarPanel;
import org.schwiet.LincolnLog.ui.components.ComponentFactory;
import org.schwiet.LincolnLog.ui.components.ConfirmationPanel;
import org.schwiet.LincolnLog.ui.components.summary.SummaryDisplay;
import org.schwiet.LincolnLog.ui.components.summary.SummaryView;
import org.schwiet.LincolnLog.ui.components.TransactionTable;
import org.schwiet.LincolnLog.ui.delegates.TransactionTableUI;
import org.schwiet.LincolnLog.ui.utils.LayoutUtility;
import org.schwiet.LincolnLog.ui.utils.PlatformUtils;
import org.schwiet.LincolnLog.ui.utils.ViewSetupManager;

/**
 *
 * @author sethschwiethale
 */
public class LincolnLogLite extends javax.swing.JFrame implements ViewSetupManager,
        TransitionTarget {

    /*
     * JPanels
     */
    JPanel bottomBar,
            headerBar,
            viewPanel,
            confirmPanel = ConfirmationPanel.getInstance(),
            newTransPanel = NewTransactionForm.getInstance();
    /*
     * JButtons
     */
    JButton addDivvyButton,
            removeDivvyButton,
            editDivvyButton,
            refreshButton;
    /*
     * Animations
     */
    private View view = View.TRANSACTION;
    private Animator viewAnimator = new Animator(600);
    private ScreenTransition transition;

    private static SummaryDisplay summary = null;
    /*
     *
     */
    static Logger logger = Logger.getLogger(LincolnLogLite.class);

    /** Creates new form LincolnLogLite */
    public LincolnLogLite() {
//        BasicConfigurator.configure();
        /*
         *
         */
        platformCheck();
        this.getRootPane().putClientProperty("apple.awt.brushMetalLook", Boolean.TRUE);
        this.setBackground(new Color(0, 0, 0, 0));
        /*
         * auto-generated
         */
        initComponents();
        /*
         * redo layout
         */
        tweak();
        /*
         * ui
         */
        adjust();
        /*
         * animations for fading views
         */
        setupAnimations();
    }

    /*
     * CUSTOM LISTENERS
     */
    private ActionListener confirmationAction = new ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
            switch (view) {
                case EDIT_DIVVY:
                    if (DivvyForm.getInstance().updateDivvy((Divvy)divvyList.getSelectedValue())) {
                        handleViewRequest(View.TRANSACTION);
                    }
                    break;
                default:
                    break;
            }
        }
    };
    /*
     *
     */
    private ActionListener cancelAction = new ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
            switch (view) {
                case NEW_DIVVY:
                    handleViewRequest(View.TRANSACTION);
                    break;
                case EDIT_DIVVY:
                    handleViewRequest(View.TRANSACTION);
                    break;
                default:
                    break;
            }
        }
    };
    /*
     *
     */
    private ActionListener moreAction = new ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
            switch (view) {
                case NEW_DIVVY:
                    if (DivvyForm.getInstance().generateDivvy()) {
                        DivvyForm.getInstance().refreshForm();
                    }
                    break;
                default:
                    break;
            }
        }
    };

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        appAreaPanel = new javax.swing.JPanel();
        divvyScrollPane = new javax.swing.JScrollPane();
        divvyList = new javax.swing.JList();
        transactionScrollPane = new javax.swing.JScrollPane();
        transactionTable = new javax.swing.JTable();
        transactionTable = new TransactionTable();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenu2 = new javax.swing.JMenu();
        undoMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Lincoln Log Lite");

        divvyScrollPane.setBackground(new java.awt.Color(0, 0, 0));
        divvyScrollPane.setBorder(null);

        divvyList.setBackground(new java.awt.Color(0, 0, 0));
        divvyList.setOpaque(false);
        divvyScrollPane.setViewportView(divvyList);

        transactionScrollPane.setBorder(null);
        transactionTable.setUI(new TransactionTableUI());

        transactionTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        transactionTable.setRowHeight(36);
        transactionTable.setSelectionBackground(new java.awt.Color(102, 255, 153));
        transactionTable.setShowVerticalLines(false);
        transactionScrollPane.setViewportView(transactionTable);

        org.jdesktop.layout.GroupLayout appAreaPanelLayout = new org.jdesktop.layout.GroupLayout(appAreaPanel);
        appAreaPanel.setLayout(appAreaPanelLayout);
        appAreaPanelLayout.setHorizontalGroup(
            appAreaPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(appAreaPanelLayout.createSequentialGroup()
                .add(divvyScrollPane, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 210, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 87, Short.MAX_VALUE)
                .add(transactionScrollPane, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        appAreaPanelLayout.setVerticalGroup(
            appAreaPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(divvyScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)
            .add(appAreaPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(transactionScrollPane, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(23, Short.MAX_VALUE))
        );

        jMenu1.setText("File");
        jMenuBar1.add(jMenu1);

        jMenu2.setText("Edit");

        undoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.event.InputEvent.META_MASK));
        undoMenuItem.setText("Undo");
        undoMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                undoMenuItemActionPerformed(evt);
            }
        });
        jMenu2.add(undoMenuItem);

        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(appAreaPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(appAreaPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void undoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_undoMenuItemActionPerformed
        if(CommandDispatch.getInstance().canUndo()){
            CommandDispatch.getInstance().undo();
        }
    }//GEN-LAST:event_undoMenuItemActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new LincolnLogLite().setVisible(true);
            }
        });
    }
    /*
     * change layout and do any other tweaks before showing
     */

    private void tweak() {

        addDivvyButton = ComponentFactory.getIconButton(getClass().getResource("/resources/add_16.png"));
        removeDivvyButton = ComponentFactory.getIconButton(getClass().getResource("/resources/remove_16.png"));
        editDivvyButton = ComponentFactory.getIconButton(getClass().getResource("/resources/edit_16.png"));
        refreshButton = ComponentFactory.getIconButton(getClass().getResource("/resources/refresh_16.png"));
        bottomBar = ComponentFactory.getBottomBar();
        headerBar = ComponentFactory.getDarkGlassHeader();
        viewPanel = ComponentFactory.getAttentionPanel();
        summary = SummaryDisplay.Initialize(headerBar);
        /*
         * main panel
         */
        this.setLayout(LayoutUtility.getMainWindowLayout());
        this.add(headerBar, LayoutUtility.MAIN_HEADER);
        this.add(bottomBar, LayoutUtility.MAIN_BOTTOM_BAR);
        this.add(this.appAreaPanel, LayoutUtility.MAIN_APP_AREA);
        /*
         * app area panel
         */
        this.appAreaPanel.removeAll();
        this.appAreaPanel.setLayout(LayoutUtility.getAppAreaLayout());
        this.appAreaPanel.add(this.divvyScrollPane, LayoutUtility.APP_AREA_DIVVY_LIST);
        this.appAreaPanel.add(this.viewPanel, LayoutUtility.APP_AREA_CONTENT);
        /*
         * viewPanel
         */
        this.viewPanel.setLayout(LayoutUtility.getViewLayout());
        /*
         * bottom bar
         */
        bottomBar.add(removeDivvyButton, BottomBarPanel.REMOVE_BUTTON);
        bottomBar.add(addDivvyButton, BottomBarPanel.ADD_BUTTON);
        bottomBar.add(editDivvyButton, BottomBarPanel.EDIT_BUTTON);
        bottomBar.add(refreshButton, BottomBarPanel.REFRESH_BUTTON);
        /*
         *
         */
        this.setupTransactionView();

    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel appAreaPanel;
    private javax.swing.JList divvyList;
    private javax.swing.JScrollPane divvyScrollPane;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JScrollPane transactionScrollPane;
    private javax.swing.JTable transactionTable;
    private javax.swing.JMenuItem undoMenuItem;
    // End of variables declaration//GEN-END:variables

    private void adjust() {
        /*
         * set up list
         */
        DivvyManager.getInstance().installListModel(divvyList);
        DivvyUtility.installListUI(divvyList);
        ((NewTransactionForm)newTransPanel).installDivvySelector(divvyList,transactionTable);
        /*
         * table
         */
        DivvyManager.getInstance().installTransactionTableModel(transactionTable);

        divvyScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        /*
         * buttons
         */
        addDivvyButton.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addDivvyActionPerformed(evt);
            }
        });
        //edit the first selected Divvy
        editDivvyButton.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editDivvyActionPerformed(evt);
            }
        });
        //remore a divvy
        removeDivvyButton.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeDivvyActionPerformed(evt);
            }
        });
        // refresh all
        refreshButton.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(ActionEvent e) {
                resetBudget(e);
            }
        });
        ((ConfirmationPanel) confirmPanel).addCancelListener(cancelAction);
        ((ConfirmationPanel) confirmPanel).addConfirmListener(confirmationAction);
        ((ConfirmationPanel) confirmPanel).addMoreListener(moreAction);
    }
    /*
     * divvyButtonAction
     */

    private void addDivvyActionPerformed(ActionEvent evt) {
        handleViewRequest(View.NEW_DIVVY);
    }

    private void editDivvyActionPerformed(ActionEvent evt){
        handleViewRequest(View.EDIT_DIVVY);
    }
    /*
     * divvyButtonAction
     */

    private void removeDivvyActionPerformed(ActionEvent evt) {
        Object[] selection = divvyList.getSelectedValues();
        if(selection.length == 0){
            return;
        }
        CommandDispatch.getInstance().performCommand(DeleteDivviesCommand.createCommand(selection));
    }
    private void resetBudget(ActionEvent evt){
        CommandDispatch.getInstance().performCommand(ResetDivviesCommand.createCommand());
    }
    /*
     * View = NEW_DIVVY
     */

    public void setupNewDivvyView() {
        viewPanel.removeAll();
        viewPanel.setLayout(LayoutUtility.getViewLayout());
        viewPanel.add(DivvyForm.getInstance(), LayoutUtility.VIEW_CONTENT);
        ((ConfirmationPanel)confirmPanel).setUpAddView();
        viewPanel.add(this.confirmPanel, LayoutUtility.VIEW_CONFIRMATION);
        divvyList.setEnabled(false);
        DivvyForm.getInstance().refreshForm();
    }
    /*
     * View = WELCOME
     */

    public void setupWelcomeView() {
        viewPanel.removeAll();
        viewPanel.setLayout(LayoutUtility.getViewLayout());
        divvyList.setEnabled(true);
    }
    /*
     * View = EDIT_DIVVY
     */
    public void setupEditDivvyView(){
        Divvy divvy = (Divvy)divvyList.getSelectedValue();
        //if there are no selected divvies, do nothing
        if(divvy == null){
            return;
        }
        viewPanel.removeAll();
        viewPanel.setLayout(LayoutUtility.getViewLayout());
        viewPanel.add(DivvyForm.getInstance(), LayoutUtility.VIEW_CONTENT);
        ((ConfirmationPanel)confirmPanel).setUpChangeView();
        viewPanel.add(this.confirmPanel, LayoutUtility.VIEW_CONFIRMATION);
        divvyList.setEnabled(false);
        DivvyForm.getInstance().loadForm(divvy);
    }

    public void setupTransactionView() {
        viewPanel.removeAll();
        viewPanel.setLayout(LayoutUtility.getTransactionLayout());
        viewPanel.add(transactionScrollPane, LayoutUtility.VIEW_TABLE_LOC);
        viewPanel.add(newTransPanel, LayoutUtility.VIEW_NEW_TRANS);
        divvyList.setEnabled(true);
        summary.submitView(DivvySummary.getInstance());
    }
    /*
     * implementation of TransitionTarget
     */

    public void setupNextScreen() {
        switch (view) {
            case NEW_DIVVY:
                setupNewDivvyView();
                break;
            case WELCOME:
                setupWelcomeView();
                break;
            case TRANSACTION:
                setupTransactionView();
                break;
            case EDIT_DIVVY:
                setupEditDivvyView();
                break;
            default:
                break;
        }
    }
    /*
     * caled once to setup animator
     */

    private void setupAnimations() {
        viewAnimator.setAcceleration(.2f);
        viewAnimator.setDeceleration(.2f);
        transition = new ScreenTransition(viewPanel, this, viewAnimator);
    }

    /**
     * some action causes a request to change views; this method deterimines
     * what to do with that request
     * @param requestedView
     */
    public void handleViewRequest(View requestedView) {
        boolean changed = false;
        switch (view) {
            case WELCOME:
                if (requestedView == View.NEW_DIVVY) {
                    view = View.NEW_DIVVY;
                    changed = true;
                }
                break;
            case NEW_DIVVY:
                if (requestedView != View.NEW_DIVVY) {
                    view = requestedView;
                    changed = true;
                }
                break;
            case EDIT_DIVVY:
                if(requestedView != View.EDIT_DIVVY){
                    view = requestedView;
                    changed = true;
                }
                break;
            case TRANSACTION:
                if(requestedView != View.TRANSACTION){
                    view = requestedView;
                    changed = true;
                }
                break;
            default:
                changed = false;
                break;
        }
        if (changed) {
            transition.start();
        }
    }

    /**
     * other classes can submit a {@link SummaryView} to display via this method
     * @param view
     */
    public static void submitSummaryView(SummaryView view){
        summary.submitView(view);
    }

    private void platformCheck() {
        if(PlatformUtils.isMac()){
            System.setProperty("apple.laf.useScreenMenuBar", "true");
        }
    }
}
